package com.crawler.html.impl;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.List;
import java.util.logging.Level;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.crawler.dto.Parameter;
import com.crawler.html.WebSite;
import com.crawler.util.ChaoJiYing;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.SilentCssErrorHandler;
import com.gargoylesoftware.htmlunit.ThreadedRefreshHandler;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlImage;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.google.common.base.Strings;

public class XTY_Site implements WebSite {
    private Logger log = Logger.getLogger(XTY_Site.class);
    final private String url = "http://www.travelsky.com/tsky/validate";
    private WebClient webClient;
    private HtmlPage page;
    private Parameter parameter;

    public XTY_Site() throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log",
                "org.apache.commons.logging.impl.NoOpLog");
        java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(Level.OFF);
        java.util.logging.Logger.getLogger("org.apache.commons.httpclient").setLevel(Level.OFF);
        // 设置代理
//        webClient = new WebClient(BrowserVersion.CHROME, "192.168.2.49", 8080);
//        final DefaultCredentialsProvider credentialsProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
//        credentialsProvider.addCredentials("dong.tl", "~!@Tonglin3");
        // 初始化模拟浏览器设置
        webClient = new WebClient(BrowserVersion.CHROME);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        webClient.setJavaScriptTimeout(50000);
        webClient.waitForBackgroundJavaScript(50000);
        webClient.setRefreshHandler(new ThreadedRefreshHandler());
        webClient.setCssErrorHandler(new SilentCssErrorHandler());
        webClient.getOptions().setJavaScriptEnabled(false);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setRedirectEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.getOptions().setTimeout(50000);
        webClient.addRequestHeader("Referer", url);
        log.info("打开访问地址." + url);
        // 打开地址
        page = webClient.getPage(url);
    }

    @Override
    public WebSite setParameter(Parameter parameter) {
        this.parameter = parameter;
        return this;
    }

    @Override
    public WebSite enterCodeManually() throws IOException {
        final HtmlImage image = (HtmlImage) page.getElementById("img_randCode_t");
        this.parameter.setRandCode((String) JOptionPane.showInputDialog(null, "" + this.parameter.getEticketNoORIn()
                + " " + this.parameter.getPassengerName() + "的验证码:", "验证码", JOptionPane.NO_OPTION, new ImageIcon(image
                .getImageReader().read(0)), null, null));
        return this;
    }

    @Override
    public WebSite enterCodeCharge() throws IOException {
        final HtmlImage image = (HtmlImage) page.getElementById("img_randCode_t");
        BufferedImage read = image.getImageReader().read(0);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(read, "jpg", baos);
        // 采用超级鹰的在线解析验证码
        String user = "dtl5582";
        String passWD = "tonglin3";
        String res = ChaoJiYing.PostPic(user, passWD, "891814", "1104", "4", "0", "0", baos.toByteArray());
        log.info(this.parameter.getEticketNoORIn() + "返回验证码信息:" + res);
        if (!Strings.isNullOrEmpty(res)) {
            if (!Strings.isNullOrEmpty(JSON.parseObject(res).getString("pic_str")))
                this.parameter.setRandCode(JSON.parseObject(res).getString("pic_str"));
            else {
                log.info(this.parameter.getEticketNoORIn() + "返回报错信息:"
                        + ChaoJiYing.ReportError(user, passWD, "891814", JSON.parseObject(res).getString("pic_id")));
            }
        } else
            this.parameter.setRandCodeState(false);
        return this;
    }

    @Override
    public Parameter resultsOf() throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        /************** 模拟点击事件 跳转页面 start *******************/
        // 添加信息
//        ((HtmlInput) page.getElementById("eticketNoORIn")).setValueAttribute(this.parameter.getEticketNoORIn()
//                .replaceAll("-", ""));
//        ((HtmlInput) page.getElementById("passengerName_src")).setValueAttribute(this.parameter.getPassengerName());
//        ((HtmlInput) page.getElementById("passengerName")).setValueAttribute(this.parameter.getPassengerName());
//        ((HtmlInput) page.getElementById("randCode")).setValueAttribute(this.parameter.getRandCode());
//        
//        String js = "";
//        if (this.parameter.getEticketNoORIn().length() == 13 || this.parameter.getEticketNoORIn().length() == 14)
//            js = "document.getElementById('eticketNo').value=document.getElementById('eticketNoORIn').value;document.getElementById('validateFlag').value='0';document.getElementById(\"validateForm\").submit();";
//        else
//            js = "$('#invoiceNo').val($.trim($('#eticketNoORIn').val()));$('#validateFlag').val(1);document.getElementById(\"validateForm\").submit();";
//        ScriptResult result = page.executeJavaScript(js);
//
//        HtmlPage pageNew = (HtmlPage) result.getNewPage();
        /************** 模拟点击事件 跳转页面 end *******************/

        /************** 拼接请求url的方式 start *******************/

        String urlNew = "", eticketNoORIn = "", eticketNo = "", passengerName_src = "", passengerName = "", validateFlag = "", invoiceNo = "";

        passengerName_src = this.parameter.getPassengerName();
        try {
            passengerName_src = URLEncoder.encode(this.parameter.getPassengerName(), "UTF-8");
            passengerName = URLEncoder.encode(passengerName_src.toUpperCase(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
        }
        eticketNoORIn = this.parameter.getEticketNoORIn();
        if (this.parameter.getEticketNoORIn().length() == 13 || this.parameter.getEticketNoORIn().length() == 14) {
            eticketNo = eticketNoORIn.replaceAll("-", "");
            validateFlag = "0";
        } else {
            invoiceNo = eticketNoORIn;
            validateFlag = "1";
        }
        urlNew = url + "?validateFlag=" + validateFlag + "&eticketNo=" + eticketNo + "&invoiceNo=" + invoiceNo
                + "&imgSrc=%2Ftsky%2Fimages%2Floading.gif&eticketNoORIn" + "=" + eticketNoORIn + "&passengerName_src="
                + passengerName_src + "&passengerName=" + passengerName + "&isFromIndex=false&randCode="
                + this.parameter.getRandCode();
        HtmlPage pageNew = null;

        pageNew = webClient.getPage(urlNew);

        /************** 拼接请求url的方式 end *******************/

        HtmlElement span = (HtmlElement) pageNew.getByXPath("/html/body/div[2]/div[1]/div/form/div[4]/div[2]/span")
                .get(0);
        if (span.getAttribute("class").indexOf("hide") == -1)
            this.parameter.setContent(span.asText());
        else {

            @SuppressWarnings("unchecked")
            List<HtmlElement> trS = (List<HtmlElement>) pageNew
                    .getByXPath("/html/body/div[2]/div[2]/div[2]/div[1]/table/tbody/tr");
            for (HtmlElement tr : trS) {
                try {
                    if (this.parameter.comparingDate(((HtmlElement) tr.getByXPath("td[2]/div/span").get(0)).asText())) {
                        @SuppressWarnings("unchecked")
                        List<HtmlElement> state = (List<HtmlElement>) tr.getByXPath("td[4]/div");
                        if (!state.isEmpty())
                            this.parameter.stateStatistical(state.get(0).asText());
                        else
                            this.parameter.stateStatistical(null);
                    }
                } catch (ParseException e) {
                    log.error(e);
                }
            }
        }
        close();
        return this.parameter;
    }

    @Override
    public void close() {
        webClient.closeAllWindows();
    }

}
